package cn.net.xyan.image.wrap;

import cn.net.xyan.image.NativeLibraryLoad;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.LongByReference;
import com.sun.jna.ptr.PointerByReference;

import java.util.Arrays;
import java.util.List;

/**
 * Created by zarra on 2017/1/26.
 */
public class JPEG {

    public interface JPEGLib extends Library {
        JPEGLib INSTANCE = (JPEGLib)
                Native.loadLibrary((NativeLibraryLoad.extractFromJar("ImageCodec").getAbsolutePath()),
                        JPEGLib.class);

        int LOSSLESS = 0;
        int QUALITY = 1;

        int CJPEG8 = 0;
        int CJPEG12 = 1;
        int CJPEG16 = 2;
        int CJPLS = 3;

        int JCS_UNKNOWN = 0;
        int JCS_GRAYSCALE = 1;
        int JCS_RGB = 2;
        int JCS_YCbCr = 3;
        int JCS_CMYK = 4;
        int JCS_YCCK = 5;

        class ImageMeta extends Structure {

            public static class ByValue extends ImageMeta implements Structure.ByValue {
                public ByValue() {
                }

                public ByValue(Pointer p) {
                    super(p);
                }
            }

            public static class ByReference extends ImageMeta implements Structure.ByReference {
                public ByReference() {
                }

                public ByReference(Pointer p) {
                    super(p);
                }
            }

            public ImageMeta() {
            }

            public ImageMeta(Pointer p) {
                super(p);
                read();
            }

            public int width;
            public int height;
            public int channels;
            public int bitsPerSample;
            public int colorSpace;

            static List<String> fileds = Arrays.asList("width", "height", "channels", "bitsPerSample", "colorSpace");

            @Override
            protected List<String> getFieldOrder() {
                return fileds;
            }
        }

        class ImageCodecContext extends Structure {

            public static class ByValue extends ImageCodecContext implements Structure.ByValue {
                public ByValue() {
                }

                public ByValue(Pointer p) {
                    super(p);
                }
            }

            public static class ByReference extends ImageCodecContext implements Structure.ByReference {
                public ByReference() {
                }

                public ByReference(Pointer p) {
                    super(p);
                }
            }

            public ImageCodecContext() {
            }

            public ImageCodecContext(Pointer p) {
                super(p);
                read();
            }

            public Pointer input;
            public PointerByReference output;
            public long inputSize;
            public LongByReference outputSize;
            public int[] extra = new int[4];
            public ImageMeta.ByReference meta;

            static List<String> fileds = Arrays.asList("input", "output", "inputSize", "outputSize", "extra", "meta");

            @Override
            protected List<String> getFieldOrder() {
                return fileds;
            }
        }

        class ImageCodecErr extends Structure {

            public static class ByValue extends ImageCodecErr implements Structure.ByValue {
                public ByValue() {
                }

                public ByValue(Pointer p) {
                    super(p);
                }
            }

            public static class ByReference extends ImageCodecErr implements Structure.ByReference {
                public ByReference() {
                }

                public ByReference(Pointer p) {
                    super(p);
                }
            }

            public ImageCodecErr() {
            }

            public ImageCodecErr(Pointer p) {
                super(p);
                read();
            }

            public int code;
            public byte[] msg = new byte[256];

            static List<String> fileds = Arrays.asList("code", "msg");

            @Override
            protected List<String> getFieldOrder() {
                return fileds;
            }
        }

        int decode(int c, ImageCodecContext.ByReference context, ImageCodecErr.ByReference err);

        int encode(int c, ImageCodecContext.ByReference context, ImageCodecErr.ByReference err);

        void freeContextOutput(ImageCodecContext.ByReference context);
    }

}
